/***************************************************************************
 * Copyright 2012 TXT e-solutions SpA
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 * 
 * This work was performed within the IoT_at_Work Project
 * and partially funded by the European Commission's
 * 7th Framework Programme under the research area ICT-2009.1.3
 * Internet of Things and enterprise environments.
 *
 * Authors:
 *      Salvatore Piccione (TXT e-solutions SpA)
 *      Carbone Matteo
 *
 * Contributors:
 *        Domenico Rotondi (TXT e-solutions SpA)
 **************************************************************************/
package it.txt.ens.authorisationService.gui.standalone;

import it.txt.ens.authorisationService.gui.standalone.util.ApplicationPropertiesRepository;
import it.txt.ens.authorisationService.gui.standalone.util.JTextAreaStream;
import it.txt.ens.authorisationService.rabbitmq.RabbitMQCommandSender;
import it.txt.ens.authorisationService.util.AccessRequestListener;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.Toolkit;
import java.io.IOException;

import javax.swing.JButton;
import javax.swing.JDesktopPane;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JProgressBar;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;

import com.rabbitmq.client.Connection;

/**
 * This class defines the GUI of the IoT@Work ENS Authorisation Service.<br/>
 * The interface provides a set of buttons in order to perform the following activities:
 * <ul><li><b>Event Notification Service</b><ul><li><i>Start ENS</i> - starts a local instance of the RabbitMQ server</li>
 * <li><i>Stop ENS</i> - stops the local instance of the RabbitMQ server</li>
 * <li><i>Status ENS</i> - shows information about the current status of the local instance of the RabbitMQ server</li></ul>
 * </li>
 * <li><b>Open Control Panel</b> - opens a new window to send commands to the local instance of the RabbitMQ server</li>
 * <li><b>Access Request Listener</b>
 * <ul><li><i>Start Listener</i> - starts the subscriber in charge of evaluating the submitted access requests</li>
 * <li><i>Stop Listener</i> - stops the access request subscriber</li></ul></li>
 * <li><b>Write config</b> - restores the user configuration on the local instance of the RabbitMQ server according
 * what is reported in <code>/Keystore/user.xml</code></li>
 * <li><b>Read user data</b> - shows the content of <code>/Keystore/user.xml</code></li>
 * </ul>
 * 
 * @author Carbone Matteo
 * @author Salvatore Piccione (TXT e-solutions SpA - salvatore.piccione AT network.txtgroup.com)
 */

public class ENSAuthorisationServiceGUI extends JFrame {

	private static final long serialVersionUID = 7330138934947862964L;
	private JDesktopPane jDesktopPane = null; // @jve:decl-index=0:visual-constraint="-3,52"
	private JButton jButtonRunServerRabbit = null;
	private JButton jButtonStopSereverRabbit = null; // @jve:decl-index=0:
	private JTextArea jTextAreaResultServerRabbit = null;
	private JButton jButtonStatusServerRabbit = null;
	private JScrollPane jScrollPane = null;
	private JButton jButtonAutorizationServicesRPC = null;
	private JButton jButtonExit = null;
	private JProgressBar jProgressBar = null;
	private ENSAuthorisationServiceGUI instance = null;
	private boolean isConnect = false;
	private JButton jButtonControlPanel = null;
	private JButton jButtonStopListner = null;
	private Connection conn = null; // @jve:decl-index=0:
	private RabbitMQCLIHelperGUI controlPanel = new RabbitMQCLIHelperGUI(getInstance());
	private AccessRequestListener rpcListener;
	
//	private Properties mapProperties;
//    private JsonObject jsonAccessVhost;

	public ENSAuthorisationServiceGUI getInstance() {
		return instance;
	}
	
	private Connection getConn() {
		return conn;
	}

//	private void setConn(Connection conn) {
//		this.conn = conn;
//	}

	private boolean isConnect() {
		return isConnect;
	}

	private void setIsConnect(boolean isConnect) {
		this.isConnect = isConnect;
	}
	
	public ENSAuthorisationServiceGUI(AccessRequestListener rpcListener) {
	    this.rpcListener = rpcListener;
		this.inizialize();
//		this.mapProperties = properties;
//		this.jsonAccessVhost = jsonAccessVhost;
	}

	private void inizialize() {
		this.setSize(new Dimension(535, 456));
		getContentPane().add(getJDesktopPane(), null);
		this.setBackground(Color.DARK_GRAY);
		this.setResizable(false);
		setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);

		Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
		int locationX = (int) (screenSize.width) / 6;
		int locationY = (int) (screenSize.height) / 5;
		this.setLocation(new Point(locationX + 178, locationY));

		this.setTitle("ENS Authorization Service");

		instance = this;
		
		jButtonStopListner.setEnabled(false);

	}

	/**
	 * This method initializes jDesktopPane
	 * 
	 * @return javax.swing.JDesktopPane
	 */
	private JDesktopPane getJDesktopPane() {
		if (jDesktopPane == null) {
			jDesktopPane = new JDesktopPane();
			jDesktopPane.setSize(new Dimension(530, 430));
			jDesktopPane.add(getJButtonRunServerRabbit(), null);
			jDesktopPane.add(getJButtonStopSereverRabbit(), null);
			jDesktopPane.add(getJButtonStatusServerRabbit(), null);
			jDesktopPane.add(getJScrollPane(), null);
			jDesktopPane.add(getJButtonAutorizationServicesRPC(), null);
			jDesktopPane.add(getJButtonExit(), null);
//			jDesktopPane.add(getJButtonReadPermissionXML(), null);
//			jDesktopPane.add(getJButtonDefaultConfig(), null);
			jDesktopPane.add(getJProgressBar(), null);
			jDesktopPane.add(getJButtonStopListner(), null);
			jDesktopPane.add(getJButtonControlPanel(), null);
		}
		return jDesktopPane;
	}

	/**
	 * This method initializes jButtonRunServerRabbit
	 * 
	 * @return javax.swing.JButton
	 */
	private JButton getJButtonRunServerRabbit() {
		if (jButtonRunServerRabbit == null) {
			jButtonRunServerRabbit = new JButton();
			jButtonRunServerRabbit.setBounds(new Rectangle(5, 5, 90, 18));
			jButtonRunServerRabbit.setText("Start ENS");
			jButtonRunServerRabbit.setFont(new Font("Dialog", Font.BOLD, 11));
			jButtonRunServerRabbit
					.addMouseListener(new java.awt.event.MouseAdapter() {
						public void mouseClicked(java.awt.event.MouseEvent e) {
							
							RabbitMQCommandSender sc = new RabbitMQCommandSender(ApplicationPropertiesRepository.startServer);
							
							try {
								sc.send();
							} catch (IOException e1) {
								e1.printStackTrace(System.out);
							}
						}
					});
		}
		return jButtonRunServerRabbit;
	}

	/**
	 * This method initializes jButtonStopSereverRabbit
	 * 
	 * @return javax.swing.JButton
	 */
	private JButton getJButtonStopSereverRabbit() {
		if (jButtonStopSereverRabbit == null) {
			jButtonStopSereverRabbit = new JButton();
			jButtonStopSereverRabbit.setBounds(new Rectangle(194, 5, 90, 18));
			jButtonStopSereverRabbit.setText("Stop ENS");
			jButtonStopSereverRabbit.setFont(new Font("Dialog", Font.BOLD, 11));
			jButtonStopSereverRabbit
					.addMouseListener(new java.awt.event.MouseAdapter() {
						public void mouseClicked(java.awt.event.MouseEvent e) {
							RabbitMQCommandSender sc = new RabbitMQCommandSender(ApplicationPropertiesRepository.stopServer);
							try {
								if(isConnect()){
									jTextAreaResultServerRabbit.append("\nENS Shutdown in progress ... \n");
								}
								
								jProgressBar.setIndeterminate(false);
								jButtonAutorizationServicesRPC.setEnabled(true);
                                jTextAreaResultServerRabbit.append("\nENS Shutdown in progress ... \n");
                                sc.send();
							} catch (IOException e1) {
								e1.printStackTrace(System.out);
							}
						}
					});

		}
		return jButtonStopSereverRabbit;
	}

	/**
	 * This method initializes jTextAreaResultServerRabbit on this textArea are
	 * redirect all output stream of standard out
	 * 
	 * @return javax.swing.JTextArea
	 */
	public JTextArea getJTextAreaResultServerRabbit() {
		if (jTextAreaResultServerRabbit == null) {
			jTextAreaResultServerRabbit = new JTextArea();
			jTextAreaResultServerRabbit.setBackground(Color.DARK_GRAY);
			jTextAreaResultServerRabbit.setForeground(Color.CYAN);
			try {
				new JTextAreaStream()
				.redirectSystemOutputTo(jTextAreaResultServerRabbit);
			} catch (IOException ex) {
				System.out.println("ERROR: on redirect standard output!!!");
			}

		}
		return jTextAreaResultServerRabbit;
	}

	/**
	 * This method initializes jScrollPane contenent jTextArea which display
	 * standard out contains a JTextArea that shows the standard out
	 * 
	 * @return javax.swing.JScrollPane
	 */
	private JScrollPane getJScrollPane() {
		if (jScrollPane == null) {
			jScrollPane = new JScrollPane();
			jScrollPane.setBounds(new Rectangle(5, 28, 520, 353));
			jScrollPane.setViewportView(getJTextAreaResultServerRabbit());
		}
		return jScrollPane;
	}

	/**
	 * This method initializes jButtonStatusServerRabbit
	 * 
	 * @return javax.swing.JButton
	 */
	private JButton getJButtonStatusServerRabbit() {
		if (jButtonStatusServerRabbit == null) {
			jButtonStatusServerRabbit = new JButton();
			jButtonStatusServerRabbit.setBounds(new Rectangle(95, 5, 100, 18));
			jButtonStatusServerRabbit.setText("Status ENS");
			jButtonStatusServerRabbit
					.setFont(new Font("Dialog", Font.BOLD, 11));
			jButtonStatusServerRabbit
					.addMouseListener(new java.awt.event.MouseAdapter() {
						public void mouseClicked(java.awt.event.MouseEvent e) {
							RabbitMQCommandSender sc = new RabbitMQCommandSender(ApplicationPropertiesRepository.statusServer);
							
							try {
								sc.send();

							} catch (IOException e1) {
								e1.printStackTrace(System.out);
							}
						}
					});
		}
		return jButtonStatusServerRabbit;
	}

	private JButton getJButtonAutorizationServicesRPC() {
		if (jButtonAutorizationServicesRPC == null) {
			jButtonAutorizationServicesRPC = new JButton();
			jButtonAutorizationServicesRPC.setBounds(new Rectangle(5, 400, 130, 18));
			jButtonAutorizationServicesRPC.setText("Start Listener");
			jButtonAutorizationServicesRPC.setFont(new Font("Dialog",Font.BOLD, 11));
			jButtonAutorizationServicesRPC.setForeground(Color.blue);
			jButtonAutorizationServicesRPC
					.addMouseListener(new java.awt.event.MouseAdapter() {
						public void mouseClicked(java.awt.event.MouseEvent e) {
							if(jButtonAutorizationServicesRPC.isEnabled()){
								
//								try {
                                    Thread threadAutorizarionServices = new Thread(rpcListener);
                                    threadAutorizarionServices.start();
                                    //TODO LOG
//                                    jTextAreaResultServerRabbit
//                                            .setText("****** ENS Authorization Service ******\n"
//                                                    + "Virtual host:: "
//                                                    + vhostName
//                                                    + "\n"
//                                                    + "Broker address:: "
//                                                    + rabbitmqHost
//                                                    + ":"
//                                                    + rabbitmqPort
//                                                    + "\n"
//                                                    + "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n"
//                                                    + "~ Listening to incoming access requests ~\n"
//                                                    + "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n");
    
                                    jButtonAutorizationServicesRPC.setEnabled(false);
                                    jButtonStopListner.setEnabled(true);
								    
								    
									//define the connection to the vHost indicated in the config file
//									setConn(l.connection(vhostUsername,vhostPassword,vhostName,rabbitmqHost,rabbitmqPort));
									
									setIsConnect(true);
									jProgressBar.setIndeterminate(true);
									jTextAreaResultServerRabbit.setForeground(Color.cyan);
	
//									getConn().addShutdownListener(new ShutdownListener() {
//										
//										public void shutdownCompleted(ShutdownSignalException cause) {
//											String[] temp = cause.getReference().toString().split("amqp://");
//											String[] user = temp[1].split("@");
//
//											String[] temp2 = cause.getMessage().toString().split(":");
//											String msgError = "Shutdown notification received. Cause: "+temp2[0]+ "\n- "+ temp2[2]+"!\n";
//											JOptionPane.showMessageDialog(null,
//													msgError+""+
//													"- "+"The connection has been closed.\n"+
//													"- "+"User '"+user[0]+"'  has been disconnected",
//													"WARNING",
//													JOptionPane.WARNING_MESSAGE);
//
//											advancedProgressBar(0,false,false);
//											setIsConnect(false);
//											jButtonStopListner.setEnabled(false);
//											jButtonAutorizationServicesRPC.setEnabled(true);
//											jTextAreaResultServerRabbit.setForeground(Color.red);
//											jTextAreaResultServerRabbit.setText("\n" +
//													"*******************************************************\n"+
//													"*                                                     *\n" +
//													"* The connection has been closed. Check server status *\n" +
//													"*                                                     *\n" +
//													"*******************************************************");
//										}
//									});
										
//								} 
//								catch (IOException e1) {
//									e1.printStackTrace(System.out);
//									JOptionPane.showMessageDialog(null,
//											e1.getMessage(), "ERROR",
//											JOptionPane.ERROR_MESSAGE);
//								}
							}
						}
					});
		}
		return jButtonAutorizationServicesRPC;
	}

	/**
	 * This method initializes jButtonExit
	 * 
	 * @return javax.swing.JButton
	 */
	private JButton getJButtonExit() {
		if (jButtonExit == null) {
			jButtonExit = new JButton();
			jButtonExit.setBounds(new Rectangle(466, 5, 56, 18));
			jButtonExit.setText("Exit");
			jButtonExit.setFont(new Font("Dialog", Font.ITALIC, 12));

			jButtonExit.addMouseListener(new java.awt.event.MouseAdapter() {
				public void mouseClicked(java.awt.event.MouseEvent e) {
					System.exit(-1);
				}
			});

		}
		return jButtonExit;
	}

	/**
	 * This method initializes jButtonReadPermissionXML Reading of permissions
	 * user on file XML and display on video
	 * 
	 * @return javax.swing.JButton
	 */
//	private JButton getJButtonReadPermissionXML() {
//		if (jButtonReadPermissionXML == null) {
//			jButtonReadPermissionXML = new JButton();
//			jButtonReadPermissionXML
//					.setBounds(new Rectangle(395, 400, 130, 18));
//			jButtonReadPermissionXML.setText("Read user data");
//			jButtonReadPermissionXML.setFont(new Font("Dialog", Font.BOLD, 11));
//			jButtonReadPermissionXML
//					.addMouseListener(new java.awt.event.MouseAdapter() {
//						public void mouseClicked(java.awt.event.MouseEvent e) {
//							UserFileReader op = new UserFileReader();
//							String fileUserPath = ApplicationPropertiesRepository.APPLICATION_PROPERTIES.getProperty(
//									ApplicationPropertiesRepository.NAMESPACE_USER_FILE);
//							op.readPermissionXML(fileUserPath, true);
//						}
//					});
//		}
//		return jButtonReadPermissionXML;
//	}

	/**
	 * This method initializes jButtonInitServer
	 * 
	 * @return javax.swing.JButton
	 */
//	private JButton getJButtonDefaultConfig() {
//		if (jButtonDefaultConfig == null) {
//			jButtonDefaultConfig = new JButton();
//			jButtonDefaultConfig.setBounds(new Rectangle(265, 400, 130, 18));
//			jButtonDefaultConfig.setText("Write config");
//			jButtonDefaultConfig.setFont(new Font("Dialog", Font.BOLD, 11));
//			jButtonDefaultConfig
//					.addMouseListener(new java.awt.event.MouseAdapter() {
//						public void mousePressed(java.awt.event.MouseEvent e) {
//							System.out
//									.println("This procedure will take a few seconds. Please wait...");
//						}
//					});
//			jButtonDefaultConfig
//					.addMouseListener(new java.awt.event.MouseAdapter() {
//						public void mouseReleased(java.awt.event.MouseEvent e) {
//							RabbitMQUserCreator listnerConfigDefault = new RabbitMQUserCreator(
//									getInstance());
//							Thread config = new Thread(listnerConfigDefault);
//							config.start();
//						}
//					});
//		}
//		return jButtonDefaultConfig;
//	}

	/**
	 * This method initializes jProgressBar
	 * 
	 * @return javax.swing.JProgressBar
	 */
	private JProgressBar getJProgressBar() {
		if (jProgressBar == null) {
			jProgressBar = new JProgressBar();
			jProgressBar.setBounds(new Rectangle(5, 383, 520, 13));
			jProgressBar.setIndeterminate(false);
			jProgressBar.setStringPainted(false);
		}
		return jProgressBar;
	}

	public void advancedProgressBar(int value,boolean stringPainted, boolean indeterminate) {
		jProgressBar.setStringPainted(stringPainted);
		jProgressBar.setValue(value);
		jProgressBar.setIndeterminate(indeterminate);
	}


	public void mySetStringPainted(boolean value) {
		jProgressBar.setStringPainted(value);
	}

	/**
	 * This method initializes jButtonStopListner
	 * 
	 * @return javax.swing.JButton
	 */
	private JButton getJButtonStopListner() {
		if (jButtonStopListner == null) {
			jButtonStopListner = new JButton();
			jButtonStopListner.setBounds(new Rectangle(135, 400, 130, 18));
			jButtonStopListner.setText("Stop Listener");
			jButtonStopListner.setForeground(Color.blue);
			jButtonStopListner.setFont(new Font("Dialog", Font.BOLD, 11));
			jButtonStopListner
					.addMouseListener(new java.awt.event.MouseAdapter() {
						public void mouseClicked(java.awt.event.MouseEvent e) {
							if(jButtonStopListner.isEnabled()){	
								jProgressBar.setIndeterminate(false);
								if (isConnect()) {
									try {
									    if (ENSAuthorisationServiceGUI.this.rpcListener != null)
									        ENSAuthorisationServiceGUI.this.rpcListener.stop();
										
								        getConn().close();
										setIsConnect(false);
										jButtonAutorizationServicesRPC.setEnabled(true);
										jButtonStopListner.setEnabled(false);
										jTextAreaResultServerRabbit
											.append("****** Listener stopped ******\n");
									} catch (IOException e2) {
										e2.printStackTrace();
									}
								} else {
									JOptionPane.showMessageDialog(null,
											"Not connected!", "ERROR",
											JOptionPane.ERROR_MESSAGE);
								}
							}
						}
					});
		}
		return jButtonStopListner;
	}

	/**
	 * This method initializes jButtonControlPanel	
	 * 	
	 * @return javax.swing.JButton	
	 */
	private JButton getJButtonControlPanel() {
		if (jButtonControlPanel == null) {
			jButtonControlPanel = new JButton();
			jButtonControlPanel.setBounds(new Rectangle(294, 5, 162, 18));
			jButtonControlPanel.setText("Open Control Panel");
			jButtonControlPanel.setFont(new Font("Dialog", Font.BOLD, 11));
			jButtonControlPanel.setForeground(Color.blue);
			jButtonControlPanel.addMouseListener(new java.awt.event.MouseAdapter() {
				public void mouseClicked(java.awt.event.MouseEvent e) {

					if(jButtonControlPanel.getText().equals("Open Control Panel")){

						controlPanel.setVisible(true);
						
						Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
						int locationX = (int) (screenSize.width) / 3;
						int locationY = (int) (screenSize.height) / 5;
						getInstance().setLocation(new Point(locationX + 178, locationY));
						jButtonControlPanel.setText("Close Control Panel");
						jButtonControlPanel.setForeground(Color.red);
					}else if (jButtonControlPanel.getText().equals("Close Control Panel")){
						
						controlPanel.setVisible(false);
						
						Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
						int locationX = (int) (screenSize.width) / 6;
						int locationY = (int) (screenSize.height) / 5;
						getInstance().setLocation(new Point(locationX + 178, locationY));
						jButtonControlPanel.setText("Open Control Panel");
						jButtonControlPanel.setForeground(Color.blue);
					}
				}
			});
		}
		return jButtonControlPanel;
	}
}
